from django import forms
from django.core.exceptions import ValidationError
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML
from crispy_forms.bootstrap import FormActions
import json

from .models import Template, ProcessingTask, UploadedFile


class TemplateForm(forms.ModelForm):
    """模板表单"""
    
    # 配置字段（以JSON文本形式编辑）
    mapping_config_text = forms.CharField(
        widget=forms.Textarea(attrs={'rows': 10, 'class': 'form-control'}),
        required=False,
        label='映射配置 (JSON格式)',
        help_text='例如: {"Supplier": "供应商名称/Supplier:", "dir": "column", "splitter": "/"}'
    )
    
    fixed_config_text = forms.CharField(
        widget=forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
        required=False,
        label='固定值配置 (JSON格式)',
        help_text='例如: {"项目/Project": "Lippi", "发运条款/Dlv Term": "供应商自送"}'
    )
    
    pol_config_text = forms.CharField(
        widget=forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
        required=False,
        label='港口配置 (JSON格式)',
        help_text='例如: {"Shanghai": "SHA", "Ningbo": "NGB"}'
    )
    
    shipper_config_text = forms.CharField(
        widget=forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),
        required=False,
        label='发货人配置 (JSON格式)',
        help_text='例如: {"Company A": "COMP_A", "Company B": "COMP_B"}'
    )
    
    class Meta:
        model = Template
        fields = [
            'name', 'description', 'is_active', 'template_file',
            'mapping_config_text', 'fixed_config_text', 
            'pol_config_text', 'shipper_config_text'
        ]
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'description': forms.Textarea(attrs={'rows': 3, 'class': 'form-control'}),
            'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
            'template_file': forms.FileInput(attrs={'class': 'form-control'}),
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # 如果是编辑模式，将JSON配置转换为文本
        if self.instance and self.instance.pk:
            self.fields['mapping_config_text'].initial = json.dumps(
                self.instance.mapping_config, indent=2, ensure_ascii=False
            ) if self.instance.mapping_config else '{}'
            
            self.fields['fixed_config_text'].initial = json.dumps(
                self.instance.fixed_config, indent=2, ensure_ascii=False
            ) if self.instance.fixed_config else '{}'
            
            self.fields['pol_config_text'].initial = json.dumps(
                self.instance.pol_config, indent=2, ensure_ascii=False
            ) if self.instance.pol_config else '{}'
            
            self.fields['shipper_config_text'].initial = json.dumps(
                self.instance.shipper_config, indent=2, ensure_ascii=False
            ) if self.instance.shipper_config else '{}'
        
        # 设置Crispy Forms布局
        self.helper = FormHelper()
        self.helper.layout = Layout(
            Fieldset(
                '基本信息',
                Row(
                    Column('name', css_class='form-group col-md-6 mb-0'),
                    Column('is_active', css_class='form-group col-md-6 mb-0'),
                    css_class='form-row'
                ),
                'description',
                'template_file',
            ),
            Fieldset(
                '配置信息',
                HTML('<div class="alert alert-info">请输入有效的JSON格式配置。如果不确定格式，可以留空使用默认配置。</div>'),
                'mapping_config_text',
                'fixed_config_text',
                'pol_config_text',
                'shipper_config_text',
            ),
            FormActions(
                Submit('submit', '保存模板', css_class='btn btn-primary'),
                HTML('<a href="{% url "core:template_list" %}" class="btn btn-secondary ml-2">取消</a>'),
            )
        )
    
    def clean_mapping_config_text(self):
        """验证映射配置JSON格式"""
        text = self.cleaned_data.get('mapping_config_text', '').strip()
        if not text:
            return {}
        
        try:
            return json.loads(text)
        except json.JSONDecodeError as e:
            raise ValidationError(f'映射配置JSON格式错误: {str(e)}')
    
    def clean_fixed_config_text(self):
        """验证固定值配置JSON格式"""
        text = self.cleaned_data.get('fixed_config_text', '').strip()
        if not text:
            return {}
        
        try:
            return json.loads(text)
        except json.JSONDecodeError as e:
            raise ValidationError(f'固定值配置JSON格式错误: {str(e)}')
    
    def clean_pol_config_text(self):
        """验证港口配置JSON格式"""
        text = self.cleaned_data.get('pol_config_text', '').strip()
        if not text:
            return {}
        
        try:
            return json.loads(text)
        except json.JSONDecodeError as e:
            raise ValidationError(f'港口配置JSON格式错误: {str(e)}')
    
    def clean_shipper_config_text(self):
        """验证发货人配置JSON格式"""
        text = self.cleaned_data.get('shipper_config_text', '').strip()
        if not text:
            return {}
        
        try:
            return json.loads(text)
        except json.JSONDecodeError as e:
            raise ValidationError(f'发货人配置JSON格式错误: {str(e)}')
    
    def save(self, commit=True):
        """保存时将文本配置转换为JSON字段"""
        instance = super().save(commit=False)
        
        # 将文本配置保存到JSON字段
        instance.mapping_config = self.cleaned_data.get('mapping_config_text', {})
        instance.fixed_config = self.cleaned_data.get('fixed_config_text', {})
        instance.pol_config = self.cleaned_data.get('pol_config_text', {})
        instance.shipper_config = self.cleaned_data.get('shipper_config_text', {})
        
        if commit:
            instance.save()
        return instance


class ProcessingTaskForm(forms.ModelForm):
    """处理任务表单"""
    
    class Meta:
        model = ProcessingTask
        fields = ['task_name', 'template']
        widgets = {
            'task_name': forms.TextInput(attrs={'class': 'form-control'}),
            'template': forms.Select(attrs={'class': 'form-control'}),
        }
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # 只显示激活的模板
        self.fields['template'].queryset = Template.objects.filter(is_active=True)
        
        # 设置Crispy Forms布局
        self.helper = FormHelper()
        self.helper.layout = Layout(
            'task_name',
            'template',
            FormActions(
                Submit('submit', '创建任务', css_class='btn btn-primary'),
                HTML('<a href="{% url "core:task_list" %}" class="btn btn-secondary ml-2">取消</a>'),
            )
        )


class FileUploadForm(forms.Form):
    """文件上传表单"""
    
    files = forms.FileField(
        widget=forms.ClearableFileInput(attrs={
            'multiple': True,
            'class': 'form-control',
            'accept': '.xlsx,.xls,.csv,.txt'
        }),
        label='选择文件',
        help_text='支持 .xlsx, .xls, .csv, .txt 格式，单个文件最大50MB，一次最多上传10个文件'
    )
    
    file_type = forms.ChoiceField(
        choices=UploadedFile.FILE_TYPE_CHOICES,
        widget=forms.Select(attrs={'class': 'form-control'}),
        label='文件类型',
        initial='source'
    )
    
    template = forms.ModelChoiceField(
        queryset=Template.objects.filter(is_active=True),
        widget=forms.Select(attrs={'class': 'form-control'}),
        label='关联模板',
        required=False,
        help_text='可选：选择要关联的模板'
    )
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # 设置Crispy Forms布局
        self.helper = FormHelper()
        self.helper.layout = Layout(
            'files',
            Row(
                Column('file_type', css_class='form-group col-md-6 mb-0'),
                Column('template', css_class='form-group col-md-6 mb-0'),
                css_class='form-row'
            ),
            FormActions(
                Submit('submit', '上传文件', css_class='btn btn-primary'),
            )
        )
    
    def clean_files(self):
        """验证上传的文件"""
        files = self.files.getlist('files')
        
        if not files:
            raise ValidationError('请选择要上传的文件')
        
        if len(files) > 10:
            raise ValidationError('一次最多只能上传10个文件')
        
        total_size = 0
        allowed_extensions = ['.xlsx', '.xls', '.csv', '.txt']
        
        for file in files:
            # 检查文件大小
            if file.size > 50 * 1024 * 1024:  # 50MB
                raise ValidationError(f'文件 {file.name} 大小超过50MB限制')
            
            total_size += file.size
            
            # 检查文件扩展名
            file_extension = '.' + file.name.lower().split('.')[-1]
            if file_extension not in allowed_extensions:
                raise ValidationError(
                    f'文件 {file.name} 格式不支持。支持的格式：{"、".join(allowed_extensions)}'
                )
        
        # 检查总大小
        if total_size > 200 * 1024 * 1024:  # 200MB
            raise ValidationError('文件总大小不能超过200MB')
        
        return files


class TemplateSearchForm(forms.Form):
    """模板搜索表单"""
    
    search = forms.CharField(
        max_length=100,
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': '搜索模板名称或描述...',
        }),
        label='搜索'
    )
    
    is_active = forms.ChoiceField(
        choices=[('', '全部'), ('true', '已激活'), ('false', '未激活')],
        required=False,
        widget=forms.Select(attrs={'class': 'form-control'}),
        label='状态'
    )
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # 设置Crispy Forms布局
        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.layout = Layout(
            Row(
                Column('search', css_class='form-group col-md-8 mb-0'),
                Column('is_active', css_class='form-group col-md-4 mb-0'),
                css_class='form-row'
            ),
            FormActions(
                Submit('submit', '搜索', css_class='btn btn-primary btn-sm'),
                HTML('<a href="?" class="btn btn-secondary btn-sm ml-2">重置</a>'),
            )
        )


class TaskFilterForm(forms.Form):
    """任务过滤表单"""
    
    status = forms.ChoiceField(
        choices=[('', '全部状态')] + ProcessingTask.STATUS_CHOICES,
        required=False,
        widget=forms.Select(attrs={'class': 'form-control'}),
        label='任务状态'
    )
    
    template = forms.ModelChoiceField(
        queryset=Template.objects.all(),
        required=False,
        widget=forms.Select(attrs={'class': 'form-control'}),
        label='模板',
        empty_label='全部模板'
    )
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        # 设置Crispy Forms布局
        self.helper = FormHelper()
        self.helper.form_method = 'GET'
        self.helper.layout = Layout(
            Row(
                Column('status', css_class='form-group col-md-6 mb-0'),
                Column('template', css_class='form-group col-md-6 mb-0'),
                css_class='form-row'
            ),
            FormActions(
                Submit('submit', '筛选', css_class='btn btn-primary btn-sm'),
                HTML('<a href="?" class="btn btn-secondary btn-sm ml-2">重置</a>'),
            )
        )